package com.clp.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Stream;

public class FileUtil {

    /**
     * 根据文件路径名读取其中的多行内容，以带换行符的字符串格式返回(根据不同的编码)
     * 如 ：xxxx\r\ndsafafg\r\newqewqr
     *
     * @param absFilename ：文件绝对路径名
     * @return ：读取成功，返回对应内容的字符串；读取失败，返回空字符串
     */
    public static String readMultiLineTxtFile(String absFilename) {
        Path path = Paths.get(absFilename);
        Stream<String> strStream = null;
        try {
            // Files.strStream()：从path对应的文件中读取所有内容，并按行分割，返回一个 Stream<String> 对象
            strStream = Files.lines(path);
            // 将上面的流转换为一个字符串列表
            ArrayList<String> allLines = new ArrayList<>();
            strStream.forEach(new Consumer<String>() {
                @Override
                public void accept(String line) {
                    allLines.add(line);
                }
            });
            // 将上面的字符串列表用"\r\n（换行）"转义字符连接起来
            String data = String.join("\r\n", allLines);
            return data;
        } catch (Exception ex) {
//            ex.printStackTrace();
        } finally {
            // 需要关闭流，调用close()方法
            if (strStream != null) {
                strStream.close();
            }
        }

        try {
            strStream = Files.lines(path, Charset.forName("GBK"));
            ArrayList<String> allLines = new ArrayList<>();
            strStream.forEach(new Consumer<String>() {
                @Override
                public void accept(String line) {
                    allLines.add(line);
                }
            });
            String data = String.join("\r\n", allLines);
            return data;
        } catch (Exception ex) {
//            ex.printStackTrace();
        } finally {
            strStream.close();
        }
        return "";
    }

    public static List<String> readMultiLineTxtFileToArray(String absFilename) {
        Path path = Paths.get(absFilename);
        Stream<String> strStream = null;
        try {
            // Files.strStream()：从path对应的文件中读取所有内容，并按行分割，返回一个 Stream<String> 对象
            strStream = Files.lines(path);
            // 将上面的流转换为一个字符串列表
            ArrayList<String> allLines = new ArrayList<>();
            strStream.forEach(new Consumer<String>() {
                @Override
                public void accept(String line) {
                    allLines.add(line);
                }
            });
            return allLines;
        } catch (Exception ex) {
//            ex.printStackTrace();
        } finally {
            // 需要关闭流，调用close()方法
            if (strStream != null) {
                strStream.close();
            }
        }

        try {
            strStream = Files.lines(path, Charset.forName("GBK"));
            ArrayList<String> allLines = new ArrayList<>();
            strStream.forEach(new Consumer<String>() {
                @Override
                public void accept(String line) {
                    allLines.add(line);
                }
            });
            return allLines;
        } catch (Exception ex) {
//            ex.printStackTrace();
        } finally {
            strStream.close();
        }
        return new ArrayList<>();
    }

    /**
     * 根据绝对路径将文本文件读取成单行的字符串返回
     *
     * @param absFilename ： 文件的绝对路径名
     * @return : 读取成功，返回内容字符串；读取失败，返回空字符串
     */
    public static String readSingleLineTxtFile(String absFilename) {
        Path path = Paths.get(absFilename);
        Stream<String> strStream = null;
        try {
            strStream = Files.lines(path);
            // 将上面的流转换为一个字符串列表
            ArrayList<String> allLines = new ArrayList<>();
            strStream.forEach(line -> allLines.add(line));
            // 将上面的字符串列表连接起来
            String data = String.join("", allLines);
            return data;
        } catch (Exception ex) {
        } finally {
            // 需要关闭流，调用close()方法
            if (strStream != null) {
                strStream.close();
            }
        }

        try {
            strStream = Files.lines(path, Charset.forName("GBK"));
            ArrayList<String> allLines = new ArrayList<>();
            strStream.forEach(line -> allLines.add(line));
            String data = String.join("", allLines);
            return data;
        } catch (Exception ex) {
        } finally {
            strStream.close();
        }
        return "";
    }

    /**
     * 向文件中写入字符串数据
     *
     * @param absFilename ：文件绝对路径名
     * @param dataStr     ：要写入的字符串数据
     * @return ：写入成功返回true；写入失败返回false
     */
    public static boolean writeTxtFile(String absFilename, String dataStr) {
        File file = new File(absFilename);
        // 如果文件已存在，则删除
        if (file.exists()) {
            if (file.isDirectory()) {
                return false;
            }
            file.delete();
        }
        // 文件不存在，创建文件并写入数据
        boolean flag = true;
        OutputStreamWriter osWriter = null;
        try {
            // 创建新的文件
            file.createNewFile();
            if (file.exists()) {
                //创建一个用于操作文件的字节输出流对象，创建就必须明确数据存储目的地
                osWriter = new OutputStreamWriter(new FileOutputStream(file));
                osWriter.write(dataStr);
                //刷新流
                osWriter.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
            flag = false;
        } finally {
            if (osWriter != null) {
                try {
                    osWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return flag;
    }

    /**
     * 根据文件绝对路径名删除文件
     *
     * @param absFilename : 文件绝对路径名
     */
    public static void deleteFile(String absFilename) {
        File file = new File(absFilename);
        if (file.exists() && file.isFile()) {
            file.delete();
        }
    }

    /**
     * 文件复制
     * @param src
     * @param dest
     */
    public static void copyFile(File src, File dest) {
        if (src.isFile() && dest.isFile()) {
            try {
                Files.copy(src.toPath(), dest.toPath());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
